
<style scoped lang="scss">
.drawer-main {
  overflow-y: auto;
  height: calc(100vh - 240px);
  .drawer-main-content {
    margin-top: 65px;
    .auth-menu-item {
      .head {
        margin-top: 20px;
        margin-bottom: 10px;
        border-bottom: 1px solid #EBEEF5;
        padding-bottom: 5px;
        font-size: 15px;
        font-weight: 500;
        color: #000000;
      }
    }
  }
}
.drawer__footer {
  position: absolute;
  width: 100%;
  top: 45px;
  padding: 20px;
  z-index: 9999;
  background: white;
  display: flex;
  justify-content: left;
  box-shadow: 0 10px 12px rgba(0, 0, 0, 0.1);
  .cancel {
  }
  .submit {
    min-width: 200px;
  }
}
</style>

<template>
  <div class="app-container">
    <div class="">
      <el-form :inline="true" :model="listQuery">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="">
              <el-input v-model="listQueryFieldValue" placeholder="请输入内容" class="input-with-select" clearable>
                <el-select slot="prepend" v-model="listQueryField" placeholder="请选择" style="width: 120px">
                  <el-option v-for="(item,key) in listQueryFieldMap" :key="key" :value="item.field" :label="item.label">{{ item.label }}</el-option>
                </el-select>
              </el-input>
            </el-form-item>
            <el-form-item>
              <el-button v-waves plain class="filter-item" @click="resetGetList()">重置</el-button>
              <el-button v-waves type="primary" icon="el-icon-search" class="filter-item" @click="getList">搜索</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="12" style="display: flex;flex-direction: row-reverse">
            <el-form-item>
              <el-button v-permission="['action:system:role:create']" v-waves type="primary" icon="el-icon-circle-plus-outline" class="filter-item" @click="clickCreate">新增角色</el-button>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>

    <el-table
      v-loading="listLoading"
      :data="list"
      fit
      highlight-current-row
      border
      :header-cell-style="{background:'#eef1f6',color:'#606266'}"
    >
      <el-table-column align="center" type="index" width="70" label="序号" />
      <el-table-column label="角色名称" prop="name" />
      <el-table-column label="角色标识符" prop="code">
        <template v-slot="scope">
          {{ scope.row.code }}
        </template>
      </el-table-column>
      <el-table-column label="创建时间" prop="created_at" />
      <el-table-column label="修改时间" prop="updated_at" />
      <el-table-column fixed="right" label="操作">
        <template v-slot="scope">
          <el-button v-waves type="primary" size="mini" icon="el-icon-menu" @click="handleOpenDrawer(scope.row)">
            {{ hasAuthorize === true ? '关联权限' : '查看权限' }}
          </el-button>
          <el-button v-permission="['action:system:role:update']" type="primary" size="mini" icon="el-icon-edit-outline" @click="clickUpdate(scope.row)">编辑</el-button>
          <el-button v-permission="['action:system:role:delete']" type="danger" size="mini" icon="el-icon-delete" @click="clickDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.page_size" @pagination="getList" />

    <!-- 新增|编辑用户弹窗 -->
    <el-dialog v-el-drag-dialog :close-on-click-modal="false" :title="formTitle" :visible.sync="formVisible" width="30%">
      <el-form ref="refForm" :model="form" :rules="rules" label-position="left" label-width="120px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model.trim="form.name" />
        </el-form-item>
        <el-form-item label="角色标识符" prop="code">
          <template slot="label">
            角色标识符
            <el-tooltip class="item" effect="dark" content="角色标识符用于权限管理，全局唯一" placement="bottom-start">
              <i class="el-icon-question" />
            </el-tooltip>
          </template>
          <el-input v-model.trim="form.code" />
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="formVisible = false">关闭</el-button>
        <el-button v-if="form.id === 0" v-permission="['action:system:role:create']" type="primary" @click="submitCreate()">确认新增</el-button>
        <el-button v-else v-permission="['action:system:role:update']" type="primary" @click="submitUpdate()">确认修改</el-button>
      </div>
    </el-dialog>

    <!-- 关联权限 -->
    <el-drawer
      ref="drawer"
      :title="`修改角色【${roleData.name}】权限`"
      :visible.sync="drawerVisible"
      :close-on-press-escape="true"
      :wrapper-closable="true"
      :destroy-on-close="true"
      :with-header="true"
      size="40%"
      direction="rtl"
    >
      <div class="drawer-main" style="padding: 0 0 20px 20px;">
        <div class="drawer-main-content">
          <el-input v-model.trim="permissionFilterText" placeholder="输入关键字进行过滤" clearable style="width: 300px;margin-bottom: 10px;" />
          <el-tree
            ref="refPermissionTree"
            :data="permissionTree"
            show-checkbox
            node-key="id"
            :default-expand-all="permissionExpanded"
            :expand-on-click-node="false"
            :props="{ children: 'children', label: 'name', value: 'id' }"
            :default-checked-keys="roleData.permission_ids"
            :filter-node-method="filterPermissionNode"
            :check-strictly="true"
            accordion
          >
            <span slot-scope="{ node, data }" class="custom-tree-node">
              <el-tooltip v-if="data.type === 1" effect="light" :content="`权限类型【菜单栏】 权限标识符【${data.code}】`" placement="right">
                <span>{{ data.name }}</span>
              </el-tooltip>
              <el-tooltip v-if="data.type === 2" effect="light" :content="`权限类型【按钮】 权限标识符【${data.code}】`" placement="right">
                <span>{{ data.name }}</span>
              </el-tooltip>
            </span>
          </el-tree>
        </div>
      </div>
      <div class="drawer__footer" style="">
        <el-button v-if="permissionExpanded" v-waves type="primary" icon="el-icon-caret-top" class="filter-item" @click="permissionAllExpanded(false)">全部收起</el-button>
        <el-button v-else v-waves type="primary" icon="el-icon-caret-bottom" class="filter-item" @click="permissionAllExpanded(true)">全部展开</el-button>
        <el-button v-permission="['action:system:role:bindPermission']" v-waves type="primary" @click="permissionAllChecked">全选</el-button>
        <el-button v-permission="['action:system:role:bindPermission']" v-waves type="primary" @click="permissionResetChecked">清空</el-button>
        <!--<el-button v-waves class="submit" type="primary" @click="submitRolePermissionForm" :disabled="!checkPermission(['action:system:role:authorize'])" />-->
        <el-button v-permission="['action:system:role:bindPermission']" v-waves icon="el-icon-circle-check" class="submit" type="primary" @click="clickSubmitRoleBindPermissionForm">
          {{ loadingDrawerSubmit ? '提交中...' : '确认提交' }}
        </el-button>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import Pagination from '@/components/Pagination/index.vue' // Secondary package based on el-pagination
import { roleList, createRole, updateRole, deleteRole } from '@/api/system/role'
import { getPermissionTree } from '@/api/system/permission'
import { roleBindPermission } from '@/api/system/auth'
import { treeFormatEmpty } from '@/utils'
import checkPermission from '@/utils/permission'
export default {
  name: 'SystemRoleIndex',
  components: { Pagination },
  data() {
    return {
      list: null,
      total: 0,
      listLoading: false,
      listQueryFieldMap: [
        { field: 'name', label: '角色名称' },
        { field: 'code', label: '角色代码' }
      ],
      listQueryField: 'name',
      listQueryFieldValue: null,
      listQuery: {
        page: 1,
        page_size: 10,
        name: '',
        code: ''
      },
      formTitle: '新增',
      formVisible: false,
      form: {
        id: 0,
        name: '',
        code: ''
      },
      rules: {
        name: [
          { required: true, message: '请输入', trigger: 'blur' }
        ],
        code: [
          { required: true, message: '请输入', trigger: 'blur' }
        ]
      },
      roleList: [],
      drawerVisible: false,
      drawerLoading: false,
      loadingDrawerSubmit: false,
      permissionTree: [], // 权限数据
      permissionExpanded: true,
      permissionFilterText: '',
      roleData: {
        id: 0,
        name: '',
        permissions: [],
        users: [],
        permission_ids: []
      },
      hasAuthorize: false // 授权节点
    }
  },
  watch: {
    permissionFilterText(val) {
      this.$refs.refPermissionTree.filter(val)
    },
    listQueryField(newField, oldField) {
      this.listQuery[newField] = this.listQueryFieldValue
      this.listQuery[oldField] = null
    },
    listQueryFieldValue(newValue, oldValue) {
      this.listQuery[this.listQueryField] = newValue
    }
  },
  created() {
    this.getList()
    this.getPermissionTree()
    this.hasAuthorize = checkPermission(['action:system:role:bindPermission'])
  },
  methods: {
    checkPermission,
    resetGetList() {
      this.listQuery = {
        page: 1,
        page_size: 10,
        name: '',
        code: ''
      }
      this.listQueryFieldValue = null
      this.getList()
    },
    getList() {
      this.listLoading = true
      roleList(this.listQuery).then(res => {
        this.list = res.list
        this.total = res.total
      })
      this.listLoading = false
    },
    getPermissionTree() {
      getPermissionTree({}).then(res => {
        this.permissionTree = treeFormatEmpty(res.tree)
      })
    },
    resetFormData() {
      this.form = {
        id: 0,
        name: '',
        code: ''
      }
    },
    clickCreate() {
      this.resetFormData()
      this.formTitle = '新增'
      this.formVisible = true
    },
    submitCreate() {
      this.$refs['refForm'].validate((valid) => {
        if (valid) {
          createRole(this.form).then(res => {
            this.getList()
            this.$message({
              message: '创建成功',
              type: 'success'
            })
            this.formVisible = false
          }).then(res => {})
        }
      })
    },
    clickUpdate(item) {
      this.form = {
        id: item.id,
        name: item.name,
        code: item.code
      }
      this.formTitle = '编辑'
      this.formVisible = true
    },
    submitUpdate() {
      this.$refs['refForm'].validate((valid) => {
        if (valid) {
          updateRole(this.form).then(res => {
            this.getList()
            this.$message({
              message: '编辑成功',
              type: 'success'
            })
            this.formVisible = false
          }).then(res => {})
        }
      })
    },
    clickDelete(item) {
      this.$confirm(`此操作将永久删除该角色[${item.name}], 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.submitDelete(item.id)
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    submitDelete(id) {
      deleteRole({ id: id }).then(res => {
        this.getList()
        this.$message({
          message: '删除成功',
          type: 'success'
        })
        this.formVisible = false
      }).then(res => {})
    },
    handleOpenDrawer(row) {
      this.roleData = {
        id: row.id,
        name: row.name,
        menus: row.menus ?? [],
        permissions: row.permissions ?? [],
        users: row.users ?? [],
        menu_ids: [],
        permission_ids: [] // 角色关联的权限项
      }
      // 设置默认角色关联的权限项
      this.roleData.permissions.forEach(v => {
        this.roleData.permission_ids.push(v.id)
      })
      this.drawerVisible = true
    },
    clickSubmitRoleBindPermissionForm() {
      this.$confirm(`您确定要修改角色关联的权限数据吗, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.submitRolePermissionForm()
        this.getList()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    submitRolePermissionForm() {
      if (this.loadingDrawerSubmit === true) {
        this.$message({
          message: '请勿重复操作',
          type: 'warning'
        })
        return
      }
      this.loadingDrawerSubmit = true

      // 查询已选中的节点
      const permission_ids = []
      const checkedNodes = this.$refs.refPermissionTree.getCheckedNodes(true) ?? []
      if (checkedNodes && checkedNodes.length >= 0) {
        checkedNodes.forEach(v => {
          if (!permission_ids.includes(v.parent_id)) {
            permission_ids.push(v.parent_id) // 选择子节点时自动选择父节点
          }
          permission_ids.push(v.id)
        })
      }
      roleBindPermission({
        role_id: this.roleData.id,
        permission_ids: permission_ids
      }).then(res => {
        this.$message({
          message: '操作成功',
          type: 'success'
        })
      }).finally(() => {
        this.loadingDrawerSubmit = false
      })
    },
    permissionAllExpanded() {
      this.permissionExpanded = !this.permissionExpanded // 展开还是收起
      this.$refs.refPermissionTree.store._getAllNodes().forEach(v => {
        v.expanded = this.permissionExpanded
      })
    },
    permissionAllChecked() {
      this.$refs.refPermissionTree.store._getAllNodes().forEach(v => {
        v.checked = true // 设置节点选中
      })
    },
    permissionResetChecked() {
      this.$refs.refPermissionTree.setCheckedKeys([]) // 将选中设置为空
    },
    filterPermissionNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1 || data.code.indexOf(value) !== -1
    }
  }
}
</script>
